package com.myprocessing.timer;

import processing.core.PApplet;

import com.myprocessing.action.Action;

public class Timer {

	protected long begin;
	protected long end;
	protected long baseBegin;
	protected long baseEnd;
	protected long interval;
	protected long lastCheck;
	protected long lastInterval;
	protected boolean active = false;
	protected PApplet pApplet;
	
	protected Action timerBegin;
	protected Action timerEnd;
	protected Action timerInterval;
	
	public void init() {
		if (timerBegin != null) {
			timerBegin.init();
		}
		if (timerEnd != null) {
			timerEnd.init();
		}
		if (timerInterval != null) {
			timerInterval.init();
		}
	}
	
	private void trigger(long offsetTime) {
		active = true;
		begin = baseBegin + offsetTime;
		end = baseEnd + offsetTime;
	}
		
	public void trigger() {
		trigger(pApplet.millis());
	}
	
	public void update(long currentTime) {
		if (currentTime > begin && lastCheck < begin) {
			executeAction(timerBegin);
		}
		else if (currentTime > end){// && lastCheck < end) {
			active = false;
			executeAction(timerEnd);
		}
		
		if (active && (currentTime > begin) && (currentTime >= lastInterval + interval)) {
			executeAction(timerInterval);
			lastInterval = currentTime;
		}
		lastCheck = currentTime;
	}
	
	public long getElapsed() {
		return lastCheck - begin;
	}
	
	public long getRemaining() {
		return end - lastCheck;
	}
	
	protected void executeAction(Action a) {
		if (a != null) {
			a.execute();
		}
	}
	
	public long getBegin() {
		return begin;
	}
	public void setBegin(long begin) {
		this.baseBegin = begin;
		this.begin = begin;
	}
	public long getEnd() {
		return end;
	}
	public void setEnd(long end) {
		this.baseEnd = end;
		this.end = end;
	}
	public long getInterval() {
		return interval;
	}
	public void setInterval(long interval) {
		this.interval = interval;
	}

	public Action getTimerBegin() {
		return timerBegin;
	}

	public void setTimerBegin(Action timerBegin) {
		this.timerBegin = timerBegin;
	}

	public Action getTimerEnd() {
		return timerEnd;
	}

	public void setTimerEnd(Action timerEnd) {
		this.timerEnd = timerEnd;
	}

	public Action getTimerInterval() {
		return timerInterval;
	}

	public void setTimerInterval(Action timerInterval) {
		this.timerInterval = timerInterval;
	}
	
	public boolean isActive() {
		return active;
	}
	
	public void deactivate() {
		active = false;
	}

	public PApplet getPApplet() {
		return pApplet;
	}

	public void setPApplet(PApplet applet) {
		pApplet = applet;
	}
	
}
